class RefactorArticles < ActiveRecord::Migration
  def self.up
  	
content = Content.find(15)
content.content = <<-EOF
Sometimes there are times when you want to use Rails' built-in RJS features, but without hitting the server. For simplicity sake, let's imagine that you want to visually highlight an area of the page when a user clicks on a link, but you don't want to make a call to the server for something as simple as this. Well you can do just that using the `link_to_function` helper in the view.

### link\\_to\\_function

`link_to_function` is normally used to provide a clickable link on your HTML that will call a specified JavaScript function. However it can also take a `page` block in exactly the same way that you use RJS templates. When the link is clicked, it will execute the JavaScript generated by the RJS block. Take this example...

    <div id="menu">
      Make me flash!
    </div>

    <div id="highlight_link">

    <%= link_to_function "Click me!" do |page|
      page['menu'].visual_effect :highlight
      page['highlight_link'].remove
    end %>

    </div>
{:rhtml}

This litle snippet of code will create a link that when clicked, will highlight the `menu div` and then remove the actual link from the page itself. _Remember:_ you'll need to include the Prototype library for this to work, by adding `<%= javascript_include_tag :defaults %>` in the `<head>` of your HTML page.

### Obtrusive?

Some people don't like this approach, as it creates "obtrusive" JavaScript. "Obtrusive" means that the JavaScript code is mixed in with the HTML rather than being abstracted out. It, also isn't very "Railsy" using it in the view. But most of Rails' JavaScript helpers create obtrusive JavaScript, so it depends upon how puritanical you want to be. For a quick way of manipulating the DOM, this is a simple and easy time-saving method to use.

EOF

content.save!

###########################################

content = Content.find(10)
content.content = <<-EOF

### What are helpers again?

Rails' helpers are most commonly used when you're creating HTML forms. Here are some helpers you've probably used:

* `form_for`
* `text_field`
* `collection_select`

They are methods available to the view that make creating HTML code a lot easier. When you're in the process of learning what they do, it's really useful to be able to instantly see the HTML they create, and a way of doing this is to use the Rails console. 

### The Rails console 

Go to the root directory of your application, then type the following...

    ruby script/console

After a few seconds you should see something like this...

    Loading development environment (Rails 2.0.2)
    >>

You can now start interacting with your Rails application via this command line interface. 

### Example

To use helper methods, you need to prefix them with `helper`. Let's test out the `text_field` helper...

    >> helper.text_field(:book, :title)
    => "<input id=\"book_title\" name=\"book[title]\" size=\"30\" type=\"text\" />"
    >>
{:ruby}

Or maybe we want to see how `radio_button` works...

    >> helper.radio_button(:wallpaper, :colour, "Green")
    => "<input id=\"wallpaper_colour_green\" name=\"wallpaper[colour]\" type=\"radio\" value=\"Green\" />"
    >>
{:ruby}

As you can see, this is a really good way to get a feel for Rails' helpers, as you can see the results of your code instantly.

EOF

content.save!

#############################################################################

content = Content.find(9)
content.content = <<-EOF

Imagine you have a table of articles for a blog. Now imagine that for each article, you would like to be able to list all similar articles. Or a table containing people, where you would like to link related people to each other. This is a `has_and_belongs_to_many` (HABTM) association, but there's only one table involved. It's a self-referential relationship: a person has many people, and one of those people may also have many other people, and so on. So how do we implement that in Rails?

### The join table

Like all other HABTM relationships, we'll need to create a join table that keeps track of which articles are related to one another. However, in this case, both of the ids in the join table will each belong to an article. We'll want a column to keep track of the main article's `id`, and a column that contains the `id` of the related article. Let's called this join table `related_articles` and create a migration...
    
    create_table "related_articles", :force => true, :id => false do |t|
  	    t.column "related_article_id", :integer
  	    t.column "main_article_id", :integer
    end
{:ruby}

Remember that as this is a join table, it doesn't require its own `id`, so we set `:id => false`. Now let's take a look at the `Article` class...
    
### The self-referential class

`Article` is just like any other class, except we need to be verbose when defining the HABTM relationship. In a standard HABTM relationship, Rails would be able to work out the name of the join table, but in this case, the join table doesn't join two models together, it joins a model back to itself. We need to specify some additional options as follows...

    class Article < ActiveRecord::Base
	
	    has_and_belongs_to_many :related_articles, :class_name => "Article", :join_table => "related_articles", :foreign_key => "main_article_id", :association_foreign_key => "related_article_id"
	
    end
{:ruby}
    
So what do each of those options do?

* `:join_table` is where we tell Rails the name of our join table. We called it `related_articles`. 
* `:foreign_key` specifies the name of the foreign key column that contains the id of the main article, the one that is acting as a parent of the related articles: we called this `main_article_id`
* `:association_foreign_key` is the name of the foreign key column that contains the id of our related articles--the articles that "belong to" our main article 
* `:class_name` contains the name of our current class, `Article`

### Implementation

A suitable interface to allow us to add related articles would be a select drop-down list that can accept multiple options. Let's edit the form in our `new.rhtml` view to allow us to select related articles when adding a new article...

    <% form_for(@article) do |f| %>

      <b>Content</b><br />
      <%= f.text_field :content %>
  
      <b>Title</b><br />
      <%= f.text_field :title %>
   
      <b>Related articles</b><br />
      <%= f.collection_select(:related_article_ids, Article.find(:all), :id, :title, {}, :multiple => true) %>
 
      <%= f.submit "Create" %>
    
    <% end %>
{:rhtml}

We use the `collection_select` helper with the `related_article_ids` method. This method automatically becomes available when we define a HABTM relationship, and it accepts an array of ids to insert into our join table. We use `Article.find(:all)` to provide a list of all the other articles in our database, and ask `collection_select` to format them so that the `:id` gets sent when we submit the form, but the `:title` is displayed in the drop-down list. We also enable `:multiple => true` so that we can choose more than one article. 

I won't go into any further details, as drop-down lists for HABTM are a completely separate article, but don't worry--it's one I'll be writing about soon (check the right-hand side to see our very own related articles, as I might already have written it!)

EOF
  	
content.save!

############################################################

content = Content.find(7)

content.content = <<-EOF

[Sexy Migrations] [1] is a plugin that provides a more concise syntax and a few new features for Rails migrations. Most of its functionality has now been added to the Rails 2.0 core. Let's take a look...

### Shorter column syntax

If we look at an old migration file, we can see that there's usually a lot of repetition when it comes to declaring columns in a table...

    class CreateCustomer < ActiveRecord::Migration

      def self.up 
        create_table :customers do |t|

          t.column :permission_id
          t.column :class_id

          t.column :firstname,    :string, :null => false
          t.column :surname,      :string, :null => false 
          t.column :email,        :string, :null => false
          t.column :age,          :integer
          t.column :created_at,   :datetime
          t.column :updated_at,   :datetime
        end
      end

      def self.down 
        drop_table :customers
      end
    end
{:ruby}

We declare three `:string` columns and make them all `:null => false`. We also declare three `:integer` columns. Spot the repetition? Wouldn't it be better if we could do this all on one line? Well now we can. The same migration file written for Rails 2.0 looks like this...

    class CreateCustomer < ActiveRecord::Migration

      def self.up 
        create_table :customers do |t|
          t.integer   :permission_id, :class_id, :age
          t.string    :firstname, :surname, :email, :null => false
          t.timestamps
        end
      end

      def self.down 
        drop_table :customers
      end
    end
{:ruby}

Instead of the old `t.column` syntax where you specify the column type such as a symbol, such as `:string` or `:integer`, after declaring the column name, we now specify the column type directly as a method on `t` instantly saving time. 

We can also specify all the column names that are to be assigned that column type, all on one line. Any options appended to the end of the line will be applied to all the specified columns, so the `:string` columns above will all have the `null => false` declaration. 

What about `t.timestamps`? This is a shortcut for specifying Rails' `created_at` and `updated_at` automagic columns.

### Foreign keys

In the above migration, we use two foreign keys, `:class_id` and `permission_id`. We could also use the new, more readable and intuitive syntax to declare these...

    t.references :class, :permission
{:ruby}

Or we can use...

    t.belongs_to :class, :permission
{:ruby}

...whichever naming convention you prefer, they both do the same thing. There is also a `:polymorphic` option for the `references` or `belongs_to` method. This is useful when you're using polymorphic associations, as it will not only create the foreign key, but also the `type` column as well. 

For example...

    t.belongs_to :permission, :polymorphic => true
{:ruby}

...will create the `permission_id` column and also a `permission_type` column. If you wish to declare a default polymorphic type, you can use...

    t.belongs_to :permission, :polymorphic => { :default => 'Administrator' }
{:ruby}

  [1]: http://errtheblog.com/post/2381 "Sexy Migrations plugin"

EOF

content.save!

##########################################################################

content = Content.find(6)

content.content = <<-EOF

Migrations are great when you're working on an application that's already in production, but when you're in the early stages of development and your database schema is constantly changing, it can get irritating and unwieldy to keep generating migration files. But now, there's a better way... 

Auto migrations is a [plugin] [1] that will make changing your database even quicker and easier than using normal migrations. It's intended to be used in the early stages of your application development, when your database schema is fluid and constantly being changed. And best of all, it's one of my favourite kind of plugins because you can remove it at any time and it won't affect your application. Let's take a look...

### Installation

First, let's install the auto_migrations plugin...

    ruby script/plugin install svn://errtheblog.com/svn/plugins/auto_migrations

This should export it into your `vendor/plugins` directory and provide you with two new rake tasks: `rake db:auto:migrate` and `rake db:schema:to_migration`.

### schema.rb file

Now let's take a look in the `db` directory of your Rails application, where you'll find a file named `schema.rb`. This is a little bit like a consolidated migrations file, and contains the migrations syntax for your complete database schema...

    create_table "users", :force => true do |t|
      t.column "name",            :string
      t.column "hashed_password", :string
      t.column "salt",            :string
      t.column "firstname",       :string
      t.column "surname",         :string
      t.column "email",           :string
    end

    create_table "companies", :force => true do |t|
      t.column "name",        :string, :limit => 40
      t.column "description", :string
    end
{:ruby}

What the auto\\_migrations plugin does, is allow you to edit your `schema.rb` file directly, and then run `rake db:auto:migrate` to have the changes applied automatically. That's right: there's no need to generate and edit migrations files, just edit `schema.rb` directly and the plugin will detect the changes you've made as soon as you run `rake db:auto:migrate`.

### Example

In the above example `schema.rb` file, we have a `companies` table...

    create_table "companies", :force => true do |t|
      t.column "name",        :string, :limit => 40
      t.column "description", :string
    end
{:ruby}

Let's imagine that we want to add a new column--a string labelled `email` with a `limit` of 60 characters--to the `companies` table. We just edit `schema.rb` and insert an extra `t.column` line:

    create_table "companies", :force => true do |t|
      t.column "name",        :string, :limit => 40
      t.column "description", :string
      t.column "email",       :string, :limit => 60
    end
{:ruby}

Now, when we run `rake db:auto:migrate`, the email column will be added. Just run rake:

    rake db:auto:migrate

And you'll see the new column added:

    -- add_column("companies", "email", :string)
    -> 0.0216s

Now is that magic, or is that magic? It works if you delete columns too. Just delete the line containing the column from the `schema.rb` file:

    create_table "users", :force => true do |t|
      t.column "name",            :string
      t.column "hashed_password", :string
      t.column "salt",            :string
      t.column "firstname",       :string
      t.column "surname",         :string
      t.column "email",           :string
    end
{:ruby}

Let's remove the `surname` column:

    create_table "users", :force => true do |t|
      t.column "name",            :string
      t.column "hashed_password", :string
      t.column "salt",            :string
      t.column "firstname",       :string
      t.column "email",           :string
    end
{:ruby}

Then run rake:

    rake db:auto:migrate

And hey presto:

    -- remove_column("users", "surname")
    -> 0.1250s

### Limitations

Because auto\\_migrations makes several assumptions, there a few things it cannot do, namely changing the name of columns: it would simply drop the existing column and then create a new one with a new name. However, it will notice all of the following changes to `schema.rb`:

* creating and dropping tables
* creating and removing columns
* changing the types of existing columns, for example from `:string` to `:integer`
* adding and removing indexes

### db:schema:to\\_migration

And finally, when you want to start working with traditional migrations, you can get auto\\_migrations to create an initial migrations file based on the current `schema.rb`. Just run...

    rake db:schema:to_migration

And it'll create a `001_initial_schema.rb` migration file in your `db/migrate` drectory. Fantastic!

  [1]: http://errtheblog.com/posts/65-automatically "auto_migrations plugin"

EOF

content.save!

#########################################

content = Content.find(2)
content.content = <<-EOF

In this tutorial, I'll create a simple application to upload photos through a simple HTML form, and store them in the database, then render and display them on demand. The steps we'll go through are as follows:

* _Create a model._ We'll use this model for the photographs, and we'll call it "Photo"
* _Create a migration._ Use a database migration to create a table in the database to hold the photographs
* _Handle the upload._ In the view, we'll create a template containing a HTML multi-part form and a corresponding action that will allow users to upload their photograph files
* _Render the image from the database._ Once you've got the images in the database, how do you pull them out and display them again? That's what I'll show you...

### Building the foundations

First things first: let's create the photograph model from the command line:

    ruby script/generate model photo

The next step is in the controller. Let's create a `photo_admin` controller to take care of uploading, editing and deleting photos:

    ruby script/generate controller photo_admin

We'll also use Rails' scaffolding generator to create some basic actions and views that we can edit and work with: 

    ruby script/generate scaffold photo photo_admin

You might be asked by the generator script if it's okay to overwrite some of the existing controller files. Seeing as we haven't edited them even once, you can safely answer yes. 

Using migrations, we'll create a simple table containing fields to hold a description of the image, along with a binary field that will hold the binary image data itself. Open the `001_create_photos.rb` migration in the `db/migrate` directory, and edit it as follows: 

    class CreatePhotos < ActiveRecord::Migration 
        def self.up create_table :photos do |t| 
            t.column :description, :string 
            t.column :content_type, :string 
            t.column :filename, :string 
            t.column :binary_data, :binary 
        end 
    end
{:ruby}

We can then run the migration from the command line:

    rake db:migrate

If all has gone well, you should now have a table named `photos` in your database with all the fields you need to hold your image data! The next step is in the controller. Let's create a `photo_admin controller` to take care of uploading, editing and deleting photos:

    ruby script/generate controller photo_admin

We'll also use Rails' scaffolding generator to create some basic actions and views that we can edit and work with:

    ruby script/generate scaffold photo photo_admin

You might be asked by the generator script if it's okay to overwrite some of the existing controller files. Seeing as we haven't edited them even once, you can safely answer yes. 

### Creating a new photo

Excellent! Now we have the foundations laid, it's time to handle uploading a new photograph to the database. As it happens, Rails' scaffolding generator has already created the new and create actions in the `photo_admin controller` we just generated, so we don't even need to touch it yet! Instead we'll concentrate on the view for the new action.

To start with, we need to create a multipart form in the `new.rhtml` view template. This allows the browser to send image files (or any other kind of files) to the server. Let's change the existing `form_tag` helper to a `form_for` helper that will wrap our `photo` model object:

    <% form_for(:photo, @photo, :url => {:action=>'create'}, :html=> {:multipart=>true}) do |form| %>
{:rhtml}

Notice the `:multipart => true` option at the end of the tag. It's always good to use the brackets and braces for clarity when using `form_for` with a multipart option. So many errors will happen if the form isn't rendered correctly using `:multipart => true`, so it's a time saver to always make sure you get that bit right from the beginning!

Next, let's remove the scaffolded entry for `<%= render :partial => 'form' %>` and instead add two form fields: one to handle the uploading of the photo, and the other to type in a description of the photo. 

    <%= form.file_field :image_file %> 
    <%= form.text_field :description %>
{:rhtml}

To create a field in the form which allows users to browse for and upload their files, we use Rails' specific `file_field` helper. It takes the same options as the `text_field`, the object assigned to the template (in this case, form) and the method for accessing a specific attribute (in this case `image_file`) Have you spotted the first anomaly yet? No? Well let's see: we've used `:description` in the `text_field` to enter our photo's description, and that's great, because we have a corresponding description field in our database table. But we've used `image_file` to upload our image data, and there's no corresponding `image_file` field in our `photos` table. So what's going on? 

It turns out that when uploading a file, you don't get receive just one string, such as the binary image data, but a more complex object containing not just the file's binary data but its filename and content-type (such as `image/jpg` or `image/gif`). These are all stored together in `:image_file`, so what we'll need to do is extract the data and assign it the correct model attributes. The best place to do that is in the `photo` model, in `app/models/photo.rb`

    class Photo < ActiveRecord::Base 
      def image_file=(input_data) 
        self.filename = input_data.original_filename 
        self.content_type = input_data.content_type.chomp 
        self.binary_data = input_data.read 
      end 
    end
{:ruby}

Here, we take the contents of `image_file` and we use three methods to extract the data and assign it to the model attributes that match our database table: the methods are `original_filename`, `content_type` and `read`. 

#### Methods

Method                    | Purpose                      
--------------------------|------------------------------------
`original_filename`       | gives you surprisingly enough the original filename of the file
`content_type`            | provides you with the content-type of the data, such as whether it is an `image/gif` or an `audio/wav` which is useful for validation 
`read`                    | lets you actually get at the binary data 

The `chomp` method at the end of `content_type` simply removes any extraneous newline characters, to make it neater. 

Now, if you go to `yourapp/photo_admin/new` you should be able to upload a file. Try a small one at first (under 10k would be good) You'll know if it works because you'll be returned to the `/photo_admin/list` action, and you'll see the details of your file, along with a lot of gibberish under the binary column. That's because Rails is rendering your binary image data as text. Instead, we want a way to get the binary image data back out of the database and display it as an actual image... 

### Rendering an image stored in the database

To do this, we'll create a new action in our `photo_admin` controller. We'll call it `code_image`: 

	def code_image 
	end
{:ruby}

In this action, we'll get the `id` (primary key) of the image file we want to display, we'll pull it out of the database and then we'll send it to the browser and tell it to render it correctly. Let's expand:

	def code_image 
    	@image_data = Photo.find(params[:id]) 
    	@image = @image_data.binary_data 
    	send_data (@image, :type => @image_data.content_type, :filename => @image_data.filename, :disposition => 'inline') 
	end
{:ruby}

Easy! In the above action we have: 

* taken the `id` of the `Photo` from the params supplied by the form, and retrieved it from the database into the `@image_data` object
* extracted the binary data out of the `binary_data` field
* used Rails' `send_data` method to render the binary image to the browser

The `send_data` method can take several options: 

#### Options

Key                 |               Value
--------------------|--------------------------------------------------
`:filename`         | Suggests a filename for the browser to use
`:type`             | Specifies an HTTP content type. Defaults to `application/octet-stream`. We've used the existing `content_type` information that was stored in the database when we saved the image
`:disposition`      | Specifies whether the file will be shown inline or downloaded. Valid values are `inline` and `attachment` (default). We want the image displayed in the browser, so we've used inline
`:status`           | Specifies the status code to send with the response. Defaults to `200 OK`. We don't really need to worry about this today

Test it out: go to `yourapp/photo_admin/code_image/1` (or whatever the `id` is of the image you want to display - make sure it is in the database!). If all is well, your image should be rendered in the browser. 

### Displaying the image inline

Let's change the `show.rhtml` view for the `photo_admin` controller, so that instead of displaying a lot of gibberish, we can display the image itself under the "binary" column. If we open the `show.rhtml` view we should see the following: 

	<% for column in Photo.content_columns %>
    	<%= column.human_name %>
    	<%=h @photo.send(column.name) %>
	<% end %>
{:rhtml}

This code simply gets all of the column names from the database and their content and displays them automatically. This is fine for the text-based fields, but not for the binary image field. So we'll use an if condition to display the `binary_data` column differently:

    <% for column in Photo.content_columns %> 
        <%= column.human_name %>
        <% if column.name == "binary_data" %>
            <%= image_tag("/photo_admin/code_image/\#{@photo.id}", :alt => "Image") %>
        <% else %>
            <%=h @photo.send(column.name) %>
        <% end %>
    <% end %>
{:rhtml}

Try it! Go to `yourapp/photo_admin/show/1` (or whatever the image `id` is you want to display) and your image should be displayed. In the above code, we're doing the following: 

* looping through each column, and checking to see if the name of the column (`column.name`) is set to `binary_data`
* if it is, then we use the `image_tag` command to render an image. The URL of the image is simply the action that we just created in the `photo_admin` controller to encode and render the image: `photo_admin/code_image/id` where id is the "id" of the image, in this case stored in the `@photo.id` instance variable
* if the column name isn't `binary_data`, we just display the standard content of the column as text

So now you have the `code_image` method in your `photo_admin` controller, whenever you want to encode and render an image inline, you just call `photo_admin/code_image/id` as the image URL. Simple! 

### Troubleshooting Tips

If you're getting `NoMethod` or other strange errors when uploading a file, try viewing the HTML of the new form after it has been rendered by your browser and before submitting it. Then you can make sure Rails is rendering the form correctly with the `multipart` entry. If you don't see `multipart` in the `<form>` tag, then that's your problem.

EOF

content.save!

###############################################################################################################################

cheatsheet = Cheatsheet.find(17)
cheatsheet.content = <<-EOF

## Class convenience methods

### validates\\_acceptance\\_of

Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). 
  
    validates_acceptance_of :terms_of_service
    validates_acceptance_of :eula, :message => "must be abided"
{:ruby}

If the database column does not exist, the `terms_of_service` attribute is entirely virtual. This check is performed only if `terms_of_service` is not `nil` and by default on save.

##### Options {#acceptance_of_options}

Key                  | Value 
---------------------|-----------------------------------------------------
`:accept`            | Specifies value that is considered accepted. The default value is a string `"1"`, which makes it easy to relate to an HTML checkbox. This should be set to `true` if you are validating a database column, since the attribute is typecast from `"1"` to true before validation.

### validates\\_associated

Validates whether the associated object or objects are all valid themselves. Works with any kind of association.

    has_many :pages
    belongs_to :library
    validates_associated :pages, :library
{:ruby}

*Warning!* If, after the above definition, you then wrote...

    belongs_to :book
    validates_associated :book
{:ruby}

...this would specify a circular dependency and cause infinite recursion.
This validation will not fail if the association hasn't been assigned. If you want to ensure that the association is both present and guaranteed to be valid, you also need to use `validates_presence_of`

### validates\\_confirmation\\_of

Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example...

#### Model

    class Person < ActiveRecord::Base
      validates_confirmation_of :user_name, :password
      validates_confirmation_of :email_address, :message => "should match confirmation"
    end
{:ruby}

#### View

    <%= password_field "person", "password" %>
    <%= password_field "person", "password_confirmation" %>
{:rhtml}

The added `password_confirmation` attribute is virtual: it exists only as an in-memory attribute for validating the password. To achieve this, the validation adds accessors to the model for the confirmation attribute. This check is performed only if `password_confirmation` is not `nil`, and by default only on save. To require confirmation, make sure to add a presence check for the confirmation attribute...

    validates_presence_of :password_confirmation, :if => :password_changed
{:ruby}

### validates\\_each

Validates each attribute against a block.

    validates_each :first_name, :last_name do |record, attr, value|
      record.errors.add attr, 'starts with z.' if value[0] == ?z
    end
{:ruby}

### validates\\_exclusion\\_of

Validates that the value of the specified attribute is not in a particular enumerable object.

    validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here"
    validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60"
    validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension %s is not allowed"
{:ruby}

##### Options            {#exclusion_of_options}

Key                  | Value 
---------------------|-----------------------------------------------------
`:in`	             | An enumerable object of items that the value shouldn't be part of

### validates\\_format\\_of

Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.

    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
{:ruby}

Note: use `\A` and `\Z` to match the start and end of the string, `^` and `$` match the start/end of a line.

A regular expression must be provided or else an exception will be raised.

##### Options     {#format_of_options}

Key                  | Value 
---------------------|-----------------------------------------------------
`:with`	             | The regular expression used to validate the format with

### validates\\_inclusion\\_of

Validates whether the value of the specified attribute is available in a particular enumerable object.

    validates_inclusion_of :gender, :in => %w( m f ), :message => "woah! what are you then!??!!"
    validates_inclusion_of :age, :in => 0..99
    validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension %s is not included in the list" 
{:ruby}

##### Options            {#inclusion_of_options}

Key                  | Value 
---------------------|-----------------------------------------------------
`:in`	             | An enumerable object of items that the value shouldn't be part of

### validates\\_length\\_of

Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:

    validates_length_of :first_name, :maximum => 30
    validates_length_of :last_name, :maximum => 30, :message=>"less than %d if you don't mind"
    validates_length_of :fax, :in => 7..32, :allow_nil => true
    validates_length_of :phone, :in => 7..32, :allow_blank => true
    validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
    validates_length_of :fav_bra_size, :minimum => 1, :too_short => "please enter at least %d character"
    validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with %d characters... don't play me."
    validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least %d words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
{:ruby}

##### Options                {#length_of_options}

Key					| Value
--------------------|---------------------------------------------------------------
`:minimum`          | The minimum size of the attribute
`:maximum`          | The maximum size of the attribute
`:is`	            | The exact size of the attribute
`:within`	        | A range specifying the minimum and maximum size of the attribute
`:in`	            | Alias for `:within`
`:too_long`         | The error message if the attribute goes over the maximum (default is: `"is too long (maximum is %d characters)"`)
`:too_short`	    | The error message if the attribute goes under the minimum (default is: `"is too short (min is %d characters)"`)
`:wrong_length`	    | The error message if using the `:is` method and the attribute is the wrong size (default is: `"is the wrong length (should be %d characters)"`)
`:tokenizer`	    | Specifies how to split up the attribute string [^tokenizer]

### validates\\_numericality\\_of

Validates whether the value of the specified attribute is numeric by trying to convert it to a float with `Kernel.Float` (if `only_integer` is `false`) or applying it to the regular expression `/\A[+\-]?\d+\Z/` (if `only_integer` is set to `true`).
  
    validates_numericality_of :age, :greater_than => 18
{:ruby}

##### Options           {#numericality_of_options}

Key					            | Value
--------------------------------|------------------------------------------------------------
`:only_integer`	                | Specifies whether the value has to be an integer, e.g. an integral value (default is` false`)
`:greater_than`	                | Specifies the value must be greater than the supplied value
`:greater_than_or_equal_to`	    | Specifies the value must be greater than or equal the supplied value
`:equal_to`	                    | Specifies the value must be equal to the supplied value
`:less_than`	                | Specifies the value must be less than the supplied value
`:less_than_or_equal_to`	    | Specifies the value must be less than or equal the supplied value
`:odd`	                        | Specifies the value must be an odd number
`:even`	                        | Specifies the value must be an even number

### validates\\_presence\\_of

Validates that the specified attributes are not blank (as defined by blank?). Happens by default on save. 

    validates_presence_of :first_name 
{:ruby}

The `first_name` attribute must be in the object and it cannot be blank.

If you want to validate the presence of a boolean field (where the real values are `true` and `false`), you will want to use `validates_inclusion_of :field_name, :in => [true, false]` This is due to the way `blank?` handles boolean values. 

### validates\\_size\\_of

Alias for [`validates_length_of`](#validates_length_of)

### validates\\_uniqueness\\_of

Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named "davidhh".

It can also validate whether the value of the specified attributes are unique based on multiple scope parameters. For example, making sure that a teacher can only be on the schedule once per semester for a particular class.

    validates_uniqueness_of :teacher_id, :scope => [:semester_id, :class_id]
{:ruby}

When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

Because this check is performed outside the database there is still a chance that duplicate values will be inserted in two parallel transactions. To guarantee against this you should create a unique index on the field. See `add_index` for more information.

##### Options                     {#uniqueness_of_options}

Key                  | Value 
---------------------|-----------------------------------------------------
`:scope`	         | One or more columns by which to limit the scope of the uniqueness constraint
`:case_sensitive`	 | Looks for an exact match. Ignored by non-text columns (`false` by default)

## Common options

The above class convenience validation methods all take a hash of common options.

Key             | Value
----------------|-------------------------
`:message`      | a custom error message
`:on`           | specifies when this validation is active (default is `:save`, other options `:create`, `:update`)
`:allow_nil`    | skip validation if attribute is `nil` (default is `false`). Notice that for `fixnum` and `float` columns empty strings are converted to `nil`
`:allow_blank`  | if set to `true`, skips this validation if the attribute is blank (default is `false`)
`:if`           | specifies a method, `proc` or `"string"` to call to determine if the validation should occur [^if_unless]
`:unless`       | as `:if`, but used to determine if the validation should _not_ occur

## Low level validations

You can create your own validations by implementing the `validate` method (or the variations, `validate_on_create` and `validate_on_update`) in your model. The `validate` method will be called by ActiveRecord before every `save` or `update`, whilst the `validate_on_create` and `validate_on_update` methods will only be called when saving new records or updating existing records respectively. Most validation methods simply do two things:

* Inspect the attributes of an object and check whether their values pass one or more conditions (such as making sure a name attribute is not empty and/or that it matches a certain regular expression)
* If an attribute's value does not pass, add an error message to it

### Errors

Each ActiveRecord object has its own errors object which stores a list of errors related to that object and is accessible via the errors method on the object.

The errors object itself has a number of methods which enable you to both add to the list of errors, or inspect the object for errors which have already been added. For example, to add an error to the name attribute of an object, we would use the `add` method...

    object.errors.add(:name, "shouldn't be empty!")
{:ruby}

...and to retrieve errors on the `:name` attribute we could read from the errors object...

    object.errors.on(:name)    # => "shouldn't be empty!"
{:ruby}

You will find our cheatsheet ActiveRecord Validation Errors a useful resource for manipulating the errors object.

Here are some examples of implementing low-level, roll-your-own validation methods...

### Example

    class Person < ActiveRecord::Base
      protected
        def validate
          errors.add_on_empty %w( first_name last_name )
          errors.add("phone_number", "has invalid format") unless phone_number =~ /[0-9]*/
        end

        def validate_on_create # is only run the first time a new object is saved
          unless valid_discount?(membership_discount)
            errors.add("membership_discount", "has expired")
          end
        end

        def validate_on_update
          errors.add_to_base("No changes have occurred") if unchanged_attributes?
        end
    end

    person = Person.new("first_name" => "David", "phone_number" => "what?")
    person.save                         # => false (and doesn't do the save)
    person.errors.empty?                # => false
    person.errors.count                 # => 2
    person.errors.on "last_name"        # => "can't be empty"
    person.errors.on "phone_number"     # => "has invalid format"
    person.errors.each_full { |msg| puts msg }
                                    # => "Last name can't be empty"
                                    # => "Phone number has invalid format"

    person.attributes = { "last_name" => "Heinemeier", "phone_number" => "555-555" }
    person.save # => true (and person is now saved in the database)
{:ruby}

[^if_unless]: The following would call a method named `allow_validation`

        :if => :allow_validation
    {:ruby}
    The return value would be evaluated to determine whether to perform the class validation. Alternatively, the evaluation can be done via a `proc`...

        :if => Proc.new { |user| user.signup_step > 2 }). 
    {:ruby}
    The method, proc or "string" should return or evaluate to a true or false value.

[^tokenizer]: Defaults to:

        lambda { |value| value.split(//) }
    {:ruby}

    which counts individual characters. To count individual words, you would use:

        :tokenizer => lambda {|str| str.scan(/\w+/)}
    {:ruby}

EOF

cheatsheet.save!

######################################################

cheatsheet = Cheatsheet.find(1)
cheatsheet.content = <<-EOF

## Table methods

### change\\_table

Provides a block that enables you to alter columns on an existing table using various shortcut methods...

    change_table :table_name,  {options} do |t|
      t.change :column_name, :new_column_type
      t.remove :column_name
    end
{:ruby}

### create\\_table

Creates a table on the database. Creates a table called `:table_name` and makes the table object available to a block that can then add columns to it by specifying column\\_types or utilising shortcut methods such as using `belongs_to` to specify 
foreign keys...

    create_table :table_name, {table_options} do |t|
      t.string :name, {column_options}
    end
{:ruby}

#### table\\_options

Key             | Value                     | Description
----------------|---------------------------|-----------------------------------
`:force`        | `true or false`	        |  if `true`, forces drop of an existing table of the same name before creation the new one
`:temporary`    | `true or false`	        | if `true`, creates a temporary table, one that goes away when the application disconnects from the database 
`:id`	        | `true or false`	        | if `false`, defines a table with no primary key, for example when you need to define a join table 
`:primary_key`  | `:symbol`	                | overrides the default name of `:id` for the primary column. Use this to specify the name of the column in the database that Rails will use to store the primary key
`:options`	| `"string"`	                | pass raw options to your underlying database, e.g. `auto_increment = 10000`. Note that passing options will cause you to lose the default `ENGINE=InnoDB statement`

### drop\\_table

Destroys the specified table.

    drop_table :table_name
{:ruby}
    
### rename\\_table

Renames the specified table.

    rename_table :old_table_name, :new_table_name
{:ruby}

## example\\_migration.rb

    class CreateCustomers < ActiveRecord::Migration  

      def self.up
        create_table :customers, :primary_key => :customer_id, :options => "auto_increment = 10000" do |t|
          t.integer :customer_id
          t.string :name,         :limit   => 30, :null => false
          t.integer :age
          t.boolean :premium,     :default => 0
          t.binary :photo,        :limit   => 2.megabytes
          t.timestamps
          t.text :notes,          :default => "No notes recorded"
        end
        
        add_column :customers, :surname,  :string,   :limit => 50    
        
        add_column :orders,    :price,    :decimal,  :precision => 8, :scale => 2
        
        Customer.create :name => "David", :surname => "Smith", :age => "32", :premium => "1", :notes => "One of our top customers!"
      end

      def self.down 
        drop_table :customers
      end
    end
{:ruby}

## Database Mapping

Rails          | db2	        | mysql         | openbase     | Oracle
---------------|----------------|---------------|--------------|--------
`:binary`      | blob(32678)    | blob	        | object       | blob
`:boolean`     | decimal(1)     | tinyint(1)    | boolean      | number(10)
`:date`        | date	        | date	        | date	       | date
`:datetime`    | timestamp      | datetime      | datetime     | date
`:decimal`     | decimal        | decimal       | decimal      | decimal
`:float`       | float          | float	        | float	       | number
`:integer`     | int	        | int(11)       | integer      | number(38)
`:string`      | varchar(255)   | varchar(255)  | char(4096)   | varchar2(255)
`:text`        | clob(32768)    | text          | text         | clob
`:time`        | time           | time          | time         | date
`:timestamp`   | timestamp      | datetime      | timestamp    | date

* * * 

Rails          | postgresql     | sqlite        | sqlserver    | Sybase
---------------|----------------|---------------|--------------|---------------
`:binary`      | bytea          | blob          | image        | image
`:boolean`     | boolean        | boolean       | bit          | bit
`:date`        | date           | date          | datetime     | datetime
`:datetime`    | timestamp      | datetime      | datetime     | datetime
`:decimal`     | decimal        | decimal       | decimal      | decimal
`:float`       | float          | float         | float(8)     | float(8)
`:integer`     | integer        | integer       | int          | int
`:string`      | *              | varchar(255)  | varchar(255) | varchar(255)
`:text`        | text           | text          | text         | text
`:time`        | time           | datetime      | datetime     | time
`:timestamp`   | timestamp      | datetime      | datetime     | timestamp

## Rake tasks

`db:create`
`db:create:all`	
: Creates a single database specified in `config/databases.yml` for the current `RAILS_ENV` or creates all the databases

`db:drop`
`db:drop:all`
: Drops a single database specified in `config/databases.yml` for the current `RAILS_ENV` or drops all the databases

`db:fixtures:load`
: Load fixtures from `test/fixtures` into the current environment's database

`db:migrate`	
: Run all unapplied migrations

`db:migrate:up`
`db:migrate:down`	
: Move forward to the next migration, or back to the previous migration

`db:migrate VERSION=18`
: Migrate database to specific version

`db:migrate RAILS_ENV=production`	
: Use migrations to recreate tables in the testing or production databases

`db:schema:dump`	
: Create a `db/schema.rb` file that can be portably used against any database supported by ActiveRecord

`db:schema:load`
: Load a schema.rb file into the database

`db:sessions:create`
: Create a sessions table for use with `CGI::Sessions::ActiveRecordStore`

`db:sessions:clear`	
: Clear the sessions table

`db:structure:dump`
: Dump database structure to SQL file

`db:reset`
: Drops the database, creates the database and then runs migrations against the database. Takes a `VERSION` argument as well as `RAILS_ENV`

`db:rollback STEP=4`
: Takes a STEP argument to determine how many version to rollback, the default being one version

`db:test:prepare`	
: Clone your database structure into the test database

`db:version`
: Tells you the current version your database is at

## Directory structure

*    `rails_root`
    * db
*    Hello

## Shortcut methods

    t.column               t.change                t.rename
    t.remove               t.change_default	   t.references    
    t.remove_references    t.belongs_to            t.remove_belongs_to
    t.timestamps           t.index                 t.remove_index

## Column methods

### add\\_column

Creates a new column on the specified table.

    add_column :table_name, :column_name, :column_type, {column_options}
{:ruby}

#### column\\_options     {#add_column_options}

Key            | Value                   | Description
---------------|-------------------------|------------------------
`:null`	       | `true` or `false`	 | if `false`, the underlying column has a `not null` constraint added by the database engine
`:limit`       | `integer`	         | set a limit on the size of the field
`:default`     | `string`              	 | set a default value for the column
`:precision`   | `integer`	         | Specifies the precision for a `:decimal` column.
`:scale`       | `integer`	         | Specifies the scale for a `:decimal` column.

### change\\_column

Change the data type of the specified column

    change_column :table_name, :column_name, :new_column_type
{:ruby}

### rename\\_column

Renames the specified column.

    rename_column :table_name, :old_column_name, :new_column_name 
{:ruby}

### remove\\_column

Removes the specified column.

    remove_column :table_name, :column_name
{:ruby}

## Indexes

### add\\_index

Creates an index for the specified column.

    add_index :table_name, :column_name, :unique => true
{:ruby}

### remove\\_index

Remove an index from the specified column.

    remove_index :table_name, :column_name
{:ruby}

## Miscellaneous methods

### execute

Takes a single string identifying a valid SQL command to execute directly.

    execute "alter table line_items add constraint fk_line_item_products foreign key (product_id) references products(id)"
{:ruby}

### IrreversibleMigration

Use in the down method of a migration file to raise an exception when the up methods of the same migration file can not be reversed, e.g. changing a column type from `:integer` to `:string`.

    raise ActiveRecord::IrreversibleMigration
{:ruby}

## script/generate

    script/generate migration new_migration_filename 
      field_name:column_type name:string age:integer date_of_birth:date
{:plaintext}

## Loading fixtures 

Fixtures contain data which can be loaded into your database using migrations. For example, to load data into a table named customers...

+ Create a directory, db/migrate/data
+ Create a file, customers.yml, inside db/migrate/data
+ Generate a new migration file: `ruby script/generate migration load_customers_data`
+ Edit it to load data from the `customers.yml` file into your customers table

### customers.yml

    melissa:
      name: Melissa
      age: 18
    david: 
      name: David
      age: 23	
{:ruby}

### migration.rb

    require 'active_record/fixtures'
    class LoadCustomerData
     def self.up
      down
      directory = File.join(File.dirname(__FILE__), "data")
      Fixtures.create_fixtures(directory, "customers")
     end
     def self.down
      Customer.delete_all
     end
    end
{:ruby}

EOF

cheatsheet.save!

###################################

cheatsheet = Cheatsheet.find(16)
cheatsheet.content = <<-EOF# Table of Contents

## Read methods 

### \\[\\]       {#on_alias}

    object.errors[:attribute]

Alias for [`on`](#on) method.

### count

Alias for [`size`](#size)

### each

    each { |attr, msg| ... }

Yields each attribute `attr` and associated message `msg` per error added.

    class Company < ActiveRecord::Base
      validates_presence_of :name, :address, :email
      validates_length_of :name, :in => 5..30
    end

    company = Company.create(:address => '123 First St.')

    company.errors.each { |attr,msg| puts "\#{attr} - \#{msg}" } 
      # => name - is too short (minimum is 5 characters)
      # => name - can't be blank
      # => email - can't be blank
{:ruby}

### each\\_full

    each_full {|msg| ...}

Yields each full error message `msg` added. So `Person.errors.add("first_name", "can't be empty")` will be returned through iteration as `"First name can't be empty"`.

    class Company < ActiveRecord::Base
      validates_presence_of :name, :address, :email
      validates_length_of :name, :in => 5..30
    end

    company = Company.create(:address => '123 First St.')

    company.errors.each_full{|msg| puts msg } 
      # => Name is too short (minimum is 5 characters)
      # => Name can't be blank
      # => Email can't be blank
{:ruby}

### full\\_messages

Returns all the full error messages in an array.

    class Company < ActiveRecord::Base
      validates_presence_of :name, :address, :email
      validates_length_of :name, :in => 5..30
    end  

    company = Company.create(:address => '123 First St.')
  
    company.errors.full_messages 
      # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
{:ruby}

### empty?

Returns `true` if no errors have been added.

### length

Alias for [`size`](#size)

### on

    on(:attribute)

Returns `nil`, if no errors are associated with the specified attribute. Returns the error message if one error is associated with the specified attribute. Returns an array of error messages if more than one error is associated with the specified attribute.

    class Company < ActiveRecord::Base
      validates_presence_of :name, :address, :email
      validates_length_of :name, :in => 5..30
    end
  
    company = Company.create(:address => '123 First St.')

    company.errors.on(:name)      
      # => ["is too short (minimum is 5 characters)", "can't be blank"]
    company.errors.on(:email)     
      # => "can't be blank"
    company.errors.on(:address)   
      # => nil
{:ruby}

This method is also aliased as the shortcut [`[]`](#on_alias)

### on\\_base

Returns errors that have been assigned to the base object through `add_to_base` according to the normal rules of `on(:attribute)`.

### invalid? 

Returns `true` if the specified attribute has errors associated with it.

    class Company < ActiveRecord::Base
      validates_presence_of :name, :address, :email
      validates_length_of :name, :in => 5..30
    end
  
    company = Company.create(:address => '123 First St.')

    company.errors.invalid?(:name)      
      # => true
    company.errors.invalid?(:address)   
      # => false
{:ruby}

### size

Returns the total number of errors added. Two errors added to the same attribute will be counted as such.

### to\\_xml

Returns an XML representation of this error object.

## Write methods

### add 

    add(attribute, msg = @@default_error_messages[:invalid])

Adds an error message `msg` to the `attribute`, which will be returned on a call to `on(attribute)` for the same attribute and ensure that this error object returns false when asked if `empty?`. More than one error can be added to the same attribute in which case an array will be returned on a call to `on(attribute)`. If no `msg` is supplied, `"invalid"` is assumed.

### add\\_on\\_blank

    add(attribute, msg = @@default_error_messages[:blank])

Will add an error message to each of the attributes in `[attributes]` that is blank (for example, an `empty` string).

### add\\_on\\_empty

    add(attribute, msg = @@default_error_messages[:empty])

Will add an error message to each of the attributes in `attributes` that is empty.

    add_on_empty(:name, :surname, :age, "empty is bad!")
{:ruby}

### add\\_to\\_base 

    add_to_base([attributes], msg = @@default_error_messages[:empty])

Adds an error, `msg`, to the base object instead of any particular attribute. This is used to report errors that don't tie to any specific attribute, but rather to the object as a whole. These error messages don't get prepended with any field name when iterating with `each_full`, so they should be complete sentences.

    add_to_base(:name, :surname, :age, "default error message here")
{:ruby}

### clear

Removes all the errors that have been added to the object.

## Default error messages

These error messages are stored in a Rails class variable, `@@default_error_messages` and can be changed or added to as follows:

    ActiveRecord::Errors.default_error_messages[:blank] = "Your custom message here"
{:ruby}

These default error messages are used by Rails' built in validation class methods and some of the errors object's write methods such as `add_on_blank`. You may find it useful to change them if, for example, you require your error messages in a different language.

Key                 | Value
--------------------|-------------------------------
`:inclusion`        |           "is not included in the list" 
`:exclusion`        |           "is reserved"
`:invalid`          |           "is invalid"
`:confirmation`     |           "doesn't match confirmation"
`:accepted`         |           "must be accepted"
`:empty`	    |           "can't be empty"
`:blank`	    |           "can't be blank"
`:too_long`	    |           "is too long (maximum is %d characters)"
`:too_short`	    |           "is too short (maximum is %d characters)"
`:wrong_length`	    |           "is the wrong length (should be %d characters)"
`:taken`	    |           "has already been taken
`:not_a_number`	    |           "is not a number
`:greater_than`     |       "must be greater than %d"
`:greater_than_or_equal_to`  |  "must be greater than or equal to %d"
`:equal_to`	             | "must be equal to %d"
`:less_than`	             |  "must be less than %d"
`:less_than_or_equal_to`     |  "must be less than or equal to %d"
`:odd`	                     |  "must be odd"
`:even`	                     |  "must be even"

## View Helpers

### error\\_message\\_on 
   
    error_message_on(object, attribute, prepend_text = "", append_text = "", css_class = "formError")

Returns a string containing the error message attached to the attribute of the object if one exists. This error message is wrapped in a `<div>` tag, which can be extended to include a `prepend_text` and/or `append_text` (to properly explain the error), and a `css_class` to style it accordingly. Object should either be the name of an instance variable or the actual object itself. As an example, let's say you have a model `@post` that has an error message on the title attribute...

    error_message_on "post", "title"
      # => <div class="formError">can't be empty</div>
    error_message_on @post, "title"
      # => <div class="formError">can't be empty</div>
    error_message_on "post", "title", "Title simply ", " (or it won't work).", "inputError"
      # => <div class="inputError">Title simply can't be empty (or it won't work).</div>
{:ruby}

#### Options

### error\\_messages\\_for

Returns a string with a `<div>` containing all of the error messages for the objects located as instance variables by the names given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are provided.

This `<div>` can be tailored by the following options...

#### Options

Option            | Type          | Value
------------------|---------------|------------------------------------------
`:header_tag`     | String        |     Used for the header of the error `<div>` (default is `h2`)
`:id`             | String        | The class of the error `<div>` (default is `errorExplanation`)
`:class`          | String        |     The `id` of the error `<div>` (default is `errorExplanation`)
`:object`         | Object        |    The object (or array of objects) for which to display errors, if you need to escape the instance variable convention
`:object_name`    | String        |     The object name to use in the header, or any text that you prefer. If `:object_name` is not set, the name of the first object will be used
`:header_message`  | String       |  The message in the header of the error `<div>`. Pass nil or an empty string to avoid the header message altogether (default message is `"X errors prohibited this object from being saved"`)
`:message`       | String |     The explanation message after the header message and before the error list. Pass `nil` or an empty string to avoid the explanation message altogether (default message is `"There were problems with the following fields:"`)

To specify the display for one object, you simply provide its name as a parameter. For example, for the `@user` model...

    error_messages_for :user
{:ruby}

To specify more than one object, you simply list them: optionally, you can add an extra `:object_name` parameter, which will be the name used in the header message:

    error_messages_for :user_common, :user, :object_name => :user
{:ruby}

If the objects cannot be located as instance variables, you can add an extra `:object` parameter which gives the actual object (or aarray of objects to use)...

    error_messages_for :user, :object => @question.user
{:ruby}

This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what you need is significantly different from the default presentation, it makes plenty of sense to access the `object.errors` instance yourself and set it up.

EOF

cheatsheet.save!


###############

cheatsheet = Cheatsheet.find(13)
cheatsheet.content = <<-EOF

## Mailer Model

To use ActionMailer, you need to create a mailer model. Emails are defined by creating methods within the mailer model which are then used to set variables to be used in the mail template, to change options on the mail, or to add attachments.

### Mailer model generator

    ruby script/generate mailer NameOfMailer method1 method2 method3

### Example mailer model

    class OrderMailer < ActionMailer::Base

        def confirm(order,sent_at = Time.now)
            subject    "Subject line goes here"
            body       :order => order
            recipients ["bill@microsoft.com", "steve@apple.com"]
            from       "david@dizzy.co.uk"
            sent_on    sent_at
        end    
    end
{:ruby}

## Delivering mail

Once a mailer action and template are defined, you can deliver your message or create and save it for delivery later by calling the mailer class and prefixing your chosen class method with `deliver_` or `create_`

### Send mail

    Notifier.deliver_signup_notification(customer)
{:ruby}

### Create mail

    mail = Notifier.create_signup_notification(customer)
    Notifier.deliver(mail)
{:ruby}

You can pass the mailer model any variables you need to use in the generation of the email. In the example above we have passed it a variable named `customer` which could be an instance of an ActiveRecord `Customer` model. We can then access our customer's details in the mailer model.

## Multipart messages

There are two ways to send multipart email messages, explicity by manually defining each part, and implicitly by letting ActionMailer do the donkey work.

### Explicitly
 
You can explicitly define multipart messages using the part method...

    part "text/plain" do |p|
        p.body = render_message("signup-as-plain", :account => recipient)
        p.transfer_encoding = "base64"
    end
  
    part :content_type => "text/html", :body => render_message("signup-as-html", :account => recipient)
{:ruby}

### Implicitly

ActionMailer will automatically detect and use multipart templates, where each template is named after the name of the method, followed by the content type. Each such detected template will be added as a separate part to the message. For example:

    signup_notification.text.plain.erb
    signup_notification.text.html.erb
    signup_notification.text.xml.builder

Each would be rendered and added as a separate part to the message with the corresponding content type. The same body hash is passed to each template.

## Views & Templates

Like ActionController, each mailer class has a corresponding view directory in which each method of the class looks for a template with its own name. For example...

Mailer model      |   Class method         |   Corresponding template
--------------------|---------------------------|-----------------------------
`Notifier`          | `signup_notification` | `app/views/notifier/signup_notification.erb`
`Notifier`          | `despatch_alert`         | `app/views/notifier/despatch_alert.erb`
`MailingList`       | `welcome_message`        | `app/views/mailing_list/welcome_message.erb`

### Making variables available to the view

The `body` method is used to pass variables to the view. Each variable passed will be accessible as an `@instance_variable` with the name referenced by `:symbol`. 

#### Model

    body :order => order, :name => name
{:ruby}

#### View

    <%= @order %>
    <%= @name %>
{:rhtml}

## Mailer Configuration Methods

Method | Value | Purpose
-------|-------|---------
`recipients` | `[array]` _or_ `"string"` | A `"string"` containing the email of address of the recipient, or an `[array]` of `"strings"` "containing email addresses of multiple recipients. Will use the email's `To:` header.
`sent_on` | `Time` _object_ | A `Time` object which will be used to set the `Date:` header of the email. If not specified, then the current time and date will be used.
`subject` | `"string"` | The subject line to be used to set the email's `Subject:` header.
`from` | `[array]` _or_ `"string"`  | A `"string"` containing the email address to appear on the `From:` line of the email being created, or an `[array]` of `"strings"` containing multiple email addresses in the same format as recipients.
`body` | `{hash}` | The `body` method sets instance variables to be available in the view template
`attachment` | `{hash}` _or_ `block`  | Enables you to add attachments to your email message.
`bcc` | `[array]` _or_ `"string"` | Blind carbon copy recipients in the same format as `recipients`.
`cc` | `[array]` _or_ `"string"` | Carbon copy recipients in the same format as `recipients`
`content_type  |  `"string"`  | Set the `content_type` of the message. Defaults to `text/plain`
`headers`   | `{hash}`  |  A `{hash}` containing name/value pairs [^header_pairs] to be converted into abitrary header lines.
`mime_version` | `"string"` | The mime version for the message. Defaults to `1.0`
`charset` | `"string"` | The `charset` for the body and to encode the subject. Defaults to `UTF-8`
`implicit_parts_order` | `[array]`  | When an email is built implicitly, this variable controls how the parts are ordered. Defaults to `["text/html", "text/enriched", "text/plain"]`. Items that appear first in the `[array]` have higher priority in the receiving mail client and appear last in the mime encoded message.

## URLs

If your view includes URLs from the application, you need to use `url_for` in the mailer class method instead of in the view template. You can pass the result to the view via the `body` method. Unlike controllers from ActionPack, the mailer instance doesn't have any context about the incoming request, therefore you need to define the host, using `:host`. 

    body :home_page => url_for(:host => "dizzy.co.uk", :controller => "welcome", :action => "index")
{:ruby}

## ActionMailer::Base Configuration Methods

ActionMailer is configured by accessing configuration methods at the class level. For example:

    ActionMailer::Base.template_root = "/my/templates"
{:ruby}

These methods allow you to define the overall settings to be used by your application whenever it invokes ActionMailer. Define these settings in your `config/environment.rb` file using `config.action_mailer.method_name_here`. If you require different settings for each of your Rails' environments, define settings separately via `config/environments`.

Method     | Value       | Purpose
-----------|-------------|----------------
`smtp_settings` | `{hash}` | A `{hash}` of settings [^hash_of_settings] for the SMTP mail server 
`raise_delivery_errors` | `true` _or_ `false` | Whether or not errors should be raised if the email fails to be delivered.
`delivery_method` | `:smtp`, `:sendmail` _or_ `:test` | Defines a delivery method, defaults to `:smtp`
`perform_deliveries` | `true` _or_ `false` | Determines whether `deliver_*` methods are actually carried out. By default they are, but this can be turned off to help functional testing.
`template_root` | `"/path"` | The root from which template references will be made
`logger` | _Object_      | Used for generation information on the mailing run if available. Can be set to `nil` for no logging. Compatible with Ruby's own `Logger` and `Log4r` loggers.
`default_charset` |  `"string"`  | the default `charset` used for the body and to encode the subject. Defaults to `UTF-8`. You can also pick a different `charset` from inside a mailer method by setting charset
`default_mime_version` | `"string"` | The default mime version used for the message. Defaults to `1.0`. You can also pick a different value from inside a mailer method by setting `mime_version`
`default_implicit_parts_order` | `[array]` | When an email is built implicitly, this variable controls how the parts are ordered. Defaults to `["text/html", "text/enriched", "text/plain"]`. Items that appear first in the `[array]` have higher priority in the receiving mail client and appear last in the mime encoded message. You can also pick a different value from inside a mailer method by setting `implicit_parts_order`
`default_content_type`  | `"string"` | The default `content_type` used for the main part of the message. Defaults to `text/plain`. You can also pick a different value from inside a mailer method by setting `content_type`

## Setting attachments

    attachment :content_type => "image/jpeg", :body => File.read("an-image.jpg")
    attachment "application/pdf" do |a| 
      a.body = generate_your_pdf_here()
    end
{:ruby}

## smtp\\_settings

Key | Value
----|------
`:address`   | the address of the SMTP server you will be using to send email. Defaults to `localhost`
`:port`      | the port number of the SMTP server you will be using. Defaults to `25`
`:domain`    | if you need to specify a `HELO` domain, you can do it here
`:user_name` | if your mail server requires authentication, set the username in this variable
`:password`  | if your mail server requires authentication, set the password in this variable
`:authentication` | if your mail server requires authentication, you need to specify the authentication type here. This is a symbol, and one of `:plain`,       `:login`, or `:cram_md5`

[^header_pairs]: Name value pairs for setting headers  

        headers "X-Mail-Count" => 107370
    {:ruby}

EOF

cheatsheet.save!

######################################################################

cheatsheet = Cheatsheet.find(8)
cheatsheet.content = <<-EOF

## form\\_for

`form_for` is used to easily manipulate HTML forms which are based upon ActiveRecord model objects:

    <%= form_for(:customer, @customer, :url => { :controller => "customers", :action => "create" }, :html => { :multipart => true, :method => :put }) do |f| %>
      <%= f.text_field :age %> 
      <%= text_field "customer", :age %>
      <%= submit_tag %>
    <% end %>
{:rhtml}

### Parameters

Key                         | Value                    | Purpose
----------------------------|--------------------------|-----------------------
`:customer` *required*       | `:symbol` _or_ `"string"`      | The name of the model object for all the fields in the form. All input fields will be prefixed with this. Rails will also look for an `@instance_variable` with the same name which should contain an instance of an existing or new ActiveRecord model object
`@customer` *optional*	   |  _ActiveRecord model object_     | If the `@instance_variable` containing the model object is named differently, you can pass a variable containing the actual model object here
`:url` *optional*	         |  `"string"` _or_ `{hash}`	   |  The URL to post the form to. Can take an explicit url as a string, or a hash in the same format as `url_for`
`:html` *optional*	 |   `{hash}`	|  A `{hash}` of HTML attributes which will be added to the HTML `<form>` tag.
`:method` *optional*	 |   `:symbol`	|   Pass as part of the `{hash}` of HTML attributes. Can be `:put`, `:post`, `:get` or `:delete`

## Parsing form data

When a form is submitted to a Rails application, the parameters are automatically translated by Rails into the `params` object which is accessible as a hash structure. 

### Simple query strings

Key/value pairs of your form's input fields are stored simply as key/value pairs in the params hash, such as the id which is extracted by routing from the URL:

URL                        | Parameters          |  Hash constructed
---------------------------|---------------------|----------
`/customers/1`             | id=1	         | `{ :id => "1" }`
`/customers/1?color=red`   | id=1&color=red      | `{ :id => "1", :color => "red" }`

### Nesting

Square brackets `[]` are used to build more complex, nested structures:

Field helper                          | Parameters                   |  Hash constructed
--------------------------------------|------------------------------|----------
`text_field :user, :name`             | user\[name\]=David	     | `{ :user => { :name => "David" }`
`text_field "user[address]", :city`   | user\[address\]\[city\]=London   | `{ :user => { :address => { :city => "London" }}}`
`text_field "user[address]", :street` | user\[address\]\[street\]=Road   | `{ :user => { :address => { :street => "Road" }}}`

### Multiple records

Using empty square brackets `[]` after the name of a model object, such as `address[]`, will insert the `id` of the record you are editing into the input field, useful for editing multiple records on one form:

Field helper                          | Parameters                   |  Hash constructed
--------------------------------------|------------------------------|----------
`text_field "address[]", :country`    |           address\[4\]\[country\]=England           |    `{ :address => { 4 => { :country => "England" }}}`
`text_field "address[]", :town`               |   address\[4\]\[town\]=London        |    `{ :address => { 4 => { :town => "London" }}}`

If the record is new and has no id, then upon submitting the form, Rails will convert the fields into an array of hashes in order of appearance.

    text_field "address[]", :country 
    text_field "address[]", :town
    text_field "address[]", :country
    text_field "address[]", :town

    { :address => [
        { :country => "England", :town => "London" },
        { :country => "Australia", :town => "Sydney" }
      ]
    }
{:ruby}

## Example

### Controller

    def new
      @customer = Customer.new
      3.times do 
        @customer.addresses.build	
      end
    end
{:ruby}

### View

    <% form_for(@customer) do |f| %>
      <%= f.text_field :name %>
      <%= f.text_field :email %>
      <% @customer.addresses.each do |address| %>
        <% fields_for "customer[addresses][]", address do |fields| %>
          <%= fields.text_field :number %>
    	  <%= fields.text_field :street %>
      <% end %>
    <% end %>
{:rhtml}

### HTML

    <form id="new_customer" class="new_customer" method="post" action="/customers">
    <input type="text" size="30" name="customer[name]"/>
    <input type="text" size="30" name="customer[email]"/>
    <input type="text" size="30" name="customer[addresses][][number]"/>
    <input type="text" size="30" name="customer[addresses][][street]"/>
    <input type="text" size="30" name="customer[addresses][][number]"/>
    <input type="text" size="30" name="customer[addresses][][street]"/>
    <input type="text" size="30" name="customer[addresses][][number]"/>
    <input type="text" size="30" name="customer[addresses][][street]"/>
    <input type="submit" value="Create" name="commit"/>
    </form>
{:rhtml}

### params[]

    params = {
      "customer" => { "name"=>"David Pettifer",
                      "email"=>"david.p@dizzy.co.uk",
                      "addresses"=> [
                        { "number"=>"31", "street"=>"High" },
                        { "number"=>"22", "street"=>"Brook" },
                        { "number"=>"16", "street"=>"Kents" }  ]
                   } }
{:ruby}

##fields\\_for

`fields_for` creates a scope around a specific model object like `form_for`, but doesn't create the form tags themselves, making `fields_for` suitable for specifying additional model objects in the same form. See the [example](#example).

## RESTful form\\_for

When standard routes are used in a RESTful context, Rails will reflect upon the object passed to it and  automatically build a form with the relevant RESTful URL depending on whether the form is wrapping a new record (create) or an existing record (update). Nested routes will require you to be more verbose. Standard routes	

Standard routes         |  new record?   | method       | URL
------------------------|----------------|--------------|------------------
`form_for(@customer)`     |   yes	   |   POST	  |     `/customers`
`form_for(@customer)`	  |   no           |    PUT	    |   `/customers/1`

Nested routes         |   new record?   | method      |   URL
----------------------|-----------------|-------------|------------------------
`form_for(@address, :url => customer_addresses_path(@customer))`  | 	yes   |  POST	| `/customers/1/addresses`
`form_for(@address, :url => customer_addresses_path(@customer))`  | no	| PUT	| `/customers/1/addresses/24`

## Input field helpers

    f.error_messages_for
    f.check_box :terms, { :class => 'check' }, "yes", "no"
    f.file_field :image
    f.hidden_field :id
    f.label :customer, "Text for label"
    f.password_field :password
    f.radio_button :language, "French"
    f.text_area :comment, :size => "20x30", :disabled => "disabled"
    f.text_field :age, :size => "20", :class => "age_box"
{:ruby}

## Multipart form

### View

    <% form_for(@customer, :html => { :multipart => true }) do |f| %>
      <%= f.file_field :image_file %>
    <%= submit_tag %>
    <% end %>
{:rhtml}

### Model

    class Customer < ActiveRecord::Base
      def image_file=(uploaded_data)
        self.filename     = uploaded_data.original_filename
        self.image_data   = uploaded_data.read
        self.size         = uploaded_data.size
        self.content_type = uploaded_data.content_type	
      end
    end
{:ruby}
EOF

cheatsheet.save!

end

  def self.down
  end
end
